package com.leng.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leng.entity.Files;
import com.leng.response.Result;
import com.leng.service.FileService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * @作者: 冷俊杰
 * @类名: FielController类
 * @创建时间: 2022/8/28 16:01
 * @描述: 文件上传相关接口
 * @修改原图
 * @修改作者
 * @修改时间
 */
@RestController
@RequestMapping("File")
public class FielController {
    //文件存放的路径，通过Value注解来拿到yml文件中定义的路径
    @Value("${files.upload.path}")
    private String fileUploadPath;

    @Resource
    private FileService fileService;

    /**
     * 文件上传接口
     *
     * @param file 前端请求过来的文件
     * @return url 路径
     */
    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) throws IOException {
        //获取原始的名称
        String originalFilename = file.getOriginalFilename();
        //通过hutool的extName方法获取文件的类型
        String type = FileUtil.extName(originalFilename);
        //文件的大小
        long size = file.getSize();

        //定义一个文件的标识码
        String uuid = IdUtil.fastSimpleUUID();
        //最终的文件存放路径(fileUploadPath:路径 + uuid:唯一文件名 + StrUtil.DOT:. + type:后缀名)
        String fileUUID = uuid + StrUtil.DOT + type;

        File uploadfile = new File(fileUploadPath + fileUUID);
        //判断配置的文件的父级目录是否存在，不存在自动创建
        if (!uploadfile.getParentFile().exists()) {
            uploadfile.getParentFile().mkdirs();
        }

        //文件的url
        String url;
        String MD5;
        //把文件存储到磁盘中
        file.transferTo(uploadfile);
        //获取文件的MD5
        MD5 = SecureUtil.md5(uploadfile);
        //查询数据库是否有相同文件
        Files fileByMd5 = getFileByMd5(MD5);
        if (fileByMd5 != null) {//已存在
            url = fileByMd5.getUrl();
            //由于文件已存在，所以删除刚刚上传的重复文件
            uploadfile.delete();
        } else {
            //数据库不存在重复文件则不删除刚才上传的文件
            url = "http://localhost:9999/File/" + fileUUID;
            System.out.println("文件路径"+url);
        }

        //存储数据库
        Files saveFile = new Files();
        saveFile.setName(originalFilename);
        saveFile.setType(type);
        //将文件单位K转为KB
        saveFile.setSize(size / 1024);
        saveFile.setUrl(url);
        saveFile.setMd5(MD5);
        fileService.save(saveFile);

        return url;
    }

    /**
     * 文件下载接口
     * @param fileUUID 文件路径
     * @param response
     * @return url 路径
     */
    @GetMapping("/{fileUUID}")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        //根据文件的唯一标识码获取文件
        File uploadfile = new File(fileUploadPath + fileUUID);
        // 设置输出流的格式
        ServletOutputStream outputStream = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");
        //读取文件的字节流
        outputStream.write(FileUtil.readBytes(uploadfile));
        //刷新
        outputStream.flush();
        //关闭
        outputStream.close();
    }

    /**
     * 通过文件的md5查询文件
     *
     * @param MD5
     * @return
     */
    private Files getFileByMd5(String MD5) {
        //查询文件的MD5是否存在
        QueryWrapper<Files> queryWrapper = new QueryWrapper();
        queryWrapper.eq("md5", MD5);
        List<Files> filesList = fileService.list(queryWrapper);
        return filesList.size() == 0 ? null : filesList.get(0);
    }

    /**
     * 分页查询接口
     * @param current
     * @param size
     * @param name
     * @return
     */
    @PostMapping("/page")
    public Result findPage(@RequestParam(value = "current",required = true,defaultValue = "1")Integer current,
                           @RequestParam(value = "size",required = true,defaultValue = "7")Integer size,
                           @RequestParam(defaultValue = "") String name) {
        Page<Files> page=new Page<>(current,size);
        Page<Files> userByPage = fileService.getFileList(page,name);
        System.out.println(userByPage);
        return Result.ok().data("userByPage",userByPage);
    }

    /**
     * 删除文件
     * @param id
     * @return
     */
    @PostMapping("deleteFile")
    public Result deleteFile(@RequestParam("id")Integer id){
        fileService.removeById(id);
        return Result.ok();
    }
}